﻿using System;
using System.Collections.Generic;
using TimedText;
using TimedText.Formatting;
using TimedText.Styling;
using TimedText.Utilities;
using TimedText.Timing;
using TimedText.Rendering;
using TimedTextLibrary;

namespace Microsoft.Office.PowerPoint.STAMP.TimedText
{
    public class TimedTextItem
    {
        Dictionary<TimeCode, FormattingObject> m_fmt;
        bool m_parsed = false,
             m_formatted = false;
        string m_text;
        TtElement parsetree = null;
        public TtElement ParseTree
        {
            get { return parsetree; }
        }

        public TimedTextItem()
        {
        }
        /// <summary>
        /// Get/Set the source text of the Timed text
        /// </summary>
        public string SourceText
        {
            get
            {
                return m_text;
            }
            set
            {
                m_text = value;
                ResetParseEvents();
            }
        }

        public List<TimeCode> Events
        {
            get;
            set;
        }

        string m_errorString;
        public string Error
        {
            get
            {
                return m_errorString;
            }
        }

        public void Parse(TimeCode start, TimeCode end)
        {
            parsetree = null;
            try
            {
                ResetParseEvents();
                parsetree = TimedTextParser.Parse(m_text);
                if (parsetree != null)
                {
                    m_parsed = true;
                    m_formatted = false;
                    //tt parsetree = ParseTree;
                    //TimedText.Styling.FontSize.SetCellSize("32 15");
                    //parsetree.ComputeTimeIntervals(TimedText.Timing.TimeContainer.Par, start, end);
                }
            }
            catch (Exception e)
            {
                m_errorString = e.Message;
                // raise a parse event
                // MessageBox.Show(e.Message);
            }
        }

        public bool Parsed
        {
            get
            { return m_parsed; }
        }

        public bool Formatted
        {
            get
            { return m_formatted; }
        }

        private void ResetParseEvents()
        {
            m_parsed = m_formatted = false;
            Events = new List<TimeCode>();
            m_fmt = new Dictionary<TimeCode, FormattingObject>();
        }

        public void Format(TimeCode start, TimeCode end)
        {
            try
            {
                if (!m_parsed) return;

                //tt parsetree = ParseTree;
                NumberPair.SetCellSize("32 15");
                parsetree.ComputeTimeIntervals(TimeContainer.Par, start, end);

                foreach (TimeCode t in parsetree.Events)
                {
                    var formatTree = FormattingObject.RenderTree(t, parsetree);
                    if (formatTree != null)
                    {
                        m_fmt[t] = formatTree;
                        if (!Events.Contains(t))
                        {
                            Events.Add(t);
                        }
                        else
                        {
                            throw new TimedTextException("duplicate time : " + t.ToString());
                        }
                    }
                }
                m_formatted = true;
            }
            catch (TimedTextException exception)
            {
                throw;
                // raise a parse event
                //System.Windows.MessageBox.Show(exception.Message);
            }
        }

        /// <summary>
        /// Use the given renderObject to draw the next event.
        /// </summary>
        /// <param name="renderObject"></param>
        public string ShowEvent(IRenderObject renderObject, TimeCode time)
        {
            if (!m_formatted || Events.Count == 0) return "";

            renderObject.Open();
            Root f = m_fmt[time] as Root;
            f.ContextualFontSize = new FontSize("1c", null, renderObject.Width(), renderObject.Height());

            string html = f.ToHTML(renderObject);

            (f.CreateFormatter())(renderObject);

            renderObject.Close();

            return html;
        }

        public string Serialize()
        {
            if (m_parsed)
            {
                return TimedTextParser.Serialize(parsetree);
            }
            return "no parse tree";
        }


        public List<TimedTextCaption> GetTimedTextCaption(IRenderObject renderObject, TimeCode time)
        {
            if (!m_formatted || Events.Count == 0) return new List<TimedTextCaption>();

            renderObject.Open();
            Root f = m_fmt[time] as Root;
            f.ContextualFontSize = new FontSize("30px", null, renderObject.Width(), renderObject.Height());

            var caption = f.ToTimedTextCaption(renderObject, null);

            // (f.CreateFormatter())(renderObject);

            renderObject.Close();

            return caption;
        }
    }

}
